#!/usr/bin/env python
#encoding=utf-8
__author__ = 'Zhaokun'

""" wxPython实战 part 1 wxPython入门
3、在事件驱动环境中工作
"""

"""事件(event)：在你的应用程序期间发生的事情，它要求有一个响应。
事件对象(event object)：在wxPython中，它具体代表一个事件，其中包括了事件的
数据等属性。它是类wx.Event或其子类的实例，子类如wx.CommandEvent和
wx.MouseEvent。
事件类型(event type)：wxPython分配给每个事件对象的一个整数ID。事件类型给出
了关于该事件本身更多的信息。例如，wx.MouseEvent的事件类型标识了该事件是
一个鼠标单击还是一个鼠标移动。
事件源(event source)：任何wxPython对象都能产生事件。例如按钮、菜单、列表框
和任何别的窗口部件。
事件驱动(event-driven)：一个程序结构，它的大部分时间花在等待或响应事件上。
事件队列(event queue)：已发生的但未处理的事件的一个列表。
事件处理器(event handler)：响应事件时所调用的函数或方法。也称作处理器函数或
处理器方法。
事件绑定器(event binder)：一个封装了特定窗口部件，特定事件类型和一个事件处
理器的wxPython对象。为了被调用，所有事件处理器必须用一个事件绑定器注册。
wx.EvtHandler：一个wxPython类，它允许它的实例在一个特定类型，一个事件源，
和一个事件处理器之间创建绑定。注意，这个类与先前定义的事件处理函数或方法不
是同一个东西。
"""
"""wx.Event的重要的子类。
wx.CloseEvent：当一个框架关闭时触发。这个事件的类型分为一个通常的框架关闭
和一个系统关闭事件。
wx.CommandEvent：与窗口部件的简单的各种交互都将触发这个事件，如按钮单
击、菜单项选择、单选按钮选择。这些交互有它各自的事件类型。许多更复杂的窗口
部件，如列表等则定义wx.CommandEvent的子类。事件处理系统对待命令事件与其
它事件不同。
wx.KeyEvent：按按键事件。这个事件的类型分按下按键、释放按键、整个按键动
作。
wx.MouseEvent：鼠标事件。这个事件的类型分鼠标移动和鼠标敲击。对于哪个鼠
标按钮被敲击和是单击还是双击都有各自的事件类型。
wx.PaintEvent：当窗口的内容需要被重画时触发。
wx.SizeEvent：当窗口的大小或其布局改变时触发。
wx.TimerEvent：可以由类wx.Timer类创建，它是定期的事件。
"""

"""wx.MouseEvent的事件类型
它们有十四个，其中的九个涉及到了基于在按钮上的敲击，如鼠
标按下、鼠标释放、或双击事件。这九个事件类型使用了下面的名字：
wx.EVT_LEFT_DOWN
wx.EVT_LEFT_UP
wx.EVT_LEFT_DCLICK
wx.EVT_MIDDLE_DOWN
wx.EVT_MIDDLE_UP
wx.EVT_MIDDLE_DCLICK
wx.EVT_RIGHT_DOWN
wx.EVT_RIGHT_UP
wx.EVT_RIGHT_DCLICK
类型wx.EVT_MOTION产生于用户移动鼠标。
类型wx.ENTER_WINDOW和wx.LEAVE_WINDOW产生于当鼠标进入或离开一个窗
口部件时。
类型wx.EVT_MOUSEWHEEL被绑定到鼠标滚轮的活动。
类型wx.EVT_MOUSE_EVENTS一次绑定所有的鼠标事件到一个函数。
"""
"""最常使用的wx.EvtHandler的方法：
AddPendingEvent(event)：将这个event参数放入事件处理系统中。类似于
ProcessEvent()，但它实际上不会立即触发事件的处理。相反，该事件被增加到事件
队列中。适用于线程间的基于事件的通信。
Bind(event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY)：完整的说明
见3.3.1节。
GetEvtHandlerEnabled()
SetEvtHandlerEnabled( boolean)：如果处理器当前正在处理事件，则属性为True，
否则为False。
ProcessEvent(event)：把event对象放入事件处理系统中以便立即处理。
"""
#########################################################
import wx

class MenuEventFrame(wx.Frame):
    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id, 'Menus',
                          size=(300, 200))
        menuBar = wx.MenuBar()
        menu1 = wx.Menu()
        menuBar.Append(menu1,"&File")
        menuItem = menu1.Append(-1, '&Exit...')
        self.SetMenuBar(menuBar)
        self.Bind(wx.EVT_MENU, self.OnCloseMe, menuItem)
    def OnCloseMe(self, event):
        self.Close(True)
def MenuEventMain():
    app = wx.PySimpleApp()
    frame = MenuEventFrame(parent=None, id=-1)
    frame.Show()
    app.MainLoop()
########################################################################
class MouseEventFrame(wx.Frame):
    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id, 'Frame With Button',
                          size=(300, 100))
        self.panel = wx.Panel(self)
        self.btn = wx.Button(self.panel, label='Not Over',
                             pos=(100, 15))
        self.Bind(wx.EVT_BUTTON, self.OnButtonClick, self.btn) # 绑定按钮事件
        self.btn.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow) # 绑定鼠标位于其上事件
        self.btn.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow) # 绑定鼠标离开事件
    def OnButtonClick(self, event):
        self.panel.SetBackgroundColour('Green')
        self.panel.Refresh()
    def OnEnterWindow(self, event):
        self.btn.SetLabel('Over Me!')
        event.Skip()
    def OnLeaveWindow(self, event):
        self.btn.SetLabel('Not Over')
        event.Skip()
class MouseEventApp(wx.App):
    def __init__(self):
        wx.App.__init__(self, redirect=False)
    def OnInit(self):
        frame = MouseEventFrame(parent=None, id=-1)
        frame.Show()
        return True
def MouseEventMain():
    app = MouseEventApp()
    app.MainLoop()

########################
if __name__ == '__main__':
    print 'part1-3'
    MouseEventMain()
#    MenuEventMain()

